home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / Apple Game Sprockets / Examples / NSpExampleCode / NSpExampleCode.c
Encoding:
C/C++ Source or Header  |  1996-05-16  |  8.2 KB  |  418 lines  |  [TEXT/CWIE]

  1. #include <Dialogs.h>
  2. #include <Fonts.h>
  3. #include <Quickdraw.h>
  4. #include <Windows.h>
  5.  
  6. #include <NetSprocket.h>
  7.  
  8. #define CopyPStr(dst,src)    BlockMove(src,dst,src[0]+1)
  9.  
  10.  
  11. enum {
  12.     kPlayerLocation            = 0
  13. };
  14.  
  15. typedef struct PlayerLocationMessage {
  16.     NSpMessageHeader        header;
  17.     Point                    where;
  18. } PlayerLocationMessage;
  19.  
  20.  
  21. typedef struct PlayerLocation {
  22.     struct PlayerLocation*    next;
  23.     struct PlayerLocation*    prev;
  24.     NSpPlayerID                id;
  25.     Str31                    name;
  26.     Point                    where;
  27. } PlayerLocation;
  28.  
  29.  
  30. WindowPtr                    gMyWindow        = NULL;
  31. NSpGameReference            gMyGame            = NULL;
  32. Boolean                        gRunning        = false;
  33. Boolean                        gChanged        = false;
  34. PlayerLocation*                gPlayerList        = NULL;
  35. Boolean                        gHost;
  36.  
  37. void main(void);
  38. static void Init(void);
  39. static void HandleError(void);
  40. static void DoHostGame(void);
  41. static void DoJoinGame(void);
  42. static void DoHandleEvents(void);
  43. static void DoHandleMessages(void);
  44. static void DoJoinApproved(NSpJoinApprovedMessage* message);
  45. static void DoPlayerJoined(NSpPlayerJoinedMessage* message);
  46. static void DoPlayerLeft(NSpPlayerLeftMessage* message);
  47. static void DoPlayerLocation(PlayerLocationMessage* message);
  48. static void UpdateLocation(Point where);
  49. static void Redraw(void);
  50. static PlayerLocation* FindPlayer(NSpPlayerID id);
  51.  
  52.  
  53. void main(void)
  54. {
  55.     Init();
  56.     
  57.     // Let them host
  58.     DoHostGame();
  59.     
  60.     // If not hosting, let them join
  61.     if (gMyGame == NULL)
  62.     {
  63.         DoJoinGame();
  64.     }
  65.     
  66.     // Track the action
  67.     if (gMyGame != NULL)
  68.     {
  69.         gRunning = true;
  70.         
  71.         while (gRunning)
  72.         {
  73.             DoHandleEvents();
  74.             DoHandleMessages();
  75.             Redraw();
  76.         }
  77.     }
  78. }
  79.  
  80.  
  81. void Init(void)
  82. {
  83.     OSStatus        err;
  84.     Rect            bounds;
  85.     
  86.     InitGraf(&qd.thePort);
  87.     InitFonts();
  88.     InitWindows();
  89.     InitDialogs(NULL);
  90.     InitCursor();
  91.     InitMenus();
  92.     TEInit();
  93.     
  94.     bounds.top = 60;
  95.     bounds.left = 20;
  96.     bounds.bottom = bounds.top+240;
  97.     bounds.right = bounds.left+320;
  98.     
  99.     gMyWindow = NewWindow(NULL, &bounds, "\p", true, dBoxProc, (WindowPtr) -1, false, 0);
  100.     
  101.     err = NSpInitialize(550, 100000, 100, 'nspx', 100);
  102.     if (err != noErr)  HandleError();
  103. }
  104.  
  105.  
  106. void HandleError(void)
  107. {
  108.     DebugStr("\pError");
  109. }
  110.  
  111.  
  112. // Displays the Host dialog and creates a new game (NULL if cancelled)
  113. void DoHostGame(void)
  114. {
  115.     OSStatus                     err;
  116.     Boolean                        ok;
  117.     Str31                        gameName;
  118.     Str31                        playerName;
  119.     Str31                        password;
  120.     NSpProtocolListReference    protocolList;
  121.     NSpProtocolReference         atRef, ipRef;
  122.     
  123.     // Do the dialog
  124.     CopyPStr(gameName,   "\pMyGame");
  125.     CopyPStr(playerName, "\pPlayer1");
  126.     CopyPStr(password,   "\pwinbites");
  127.  
  128.     // Set up our protocol list
  129.     atRef = NSpProtocol_CreateAppleTalk(gameName, "\pNetSprocketExample", 0, 0);    
  130.     ipRef = NSpProtocol_CreateIP(2002, 0, 0);    
  131.     
  132.     err = NSpProtocolList_New(NULL, &protocolList);
  133.     if (err != noErr)  HandleError();
  134.     
  135.     err = NSpProtocolList_Append(protocolList, atRef);
  136.     if (err != noErr)  HandleError();
  137.     err = NSpProtocolList_Append(protocolList, ipRef);
  138.     if (err != noErr)  HandleError();
  139.     
  140.     ok = NSpDoModalHostDialog(protocolList, gameName, playerName, password, NULL);
  141.     if (!ok)  return;
  142.     
  143.     // Make the game object, and begin advertising
  144.     err = NSpGame_Host(&gMyGame, protocolList, 8, gameName, password, playerName, 0, kNSpClientServer, 0);
  145.     if (err != noErr)  HandleError();
  146.     
  147.     NSpProtocolList_Dispose(protocolList);
  148.     
  149.     gHost = true;
  150. }
  151.  
  152.  
  153. // Displays the Join dialog and creates a new game (NULL if cancelled)
  154. void DoJoinGame(void)
  155. {
  156.     OSStatus                err;
  157.     Str31                    playerName;
  158.     Str31                    password;
  159.     NSpAddressReference        address;
  160.             
  161.     
  162.     CopyPStr(playerName, "\pPlayer2");
  163.     CopyPStr(password,   "\pwinbites");
  164.  
  165.     address = NSpDoModalJoinDialog("\pNetSprocketExample", "\pAvailable Games:", playerName, password, NULL);
  166.  
  167.     if (address != NULL)
  168.     {
  169.         err = NSpGame_Join(&gMyGame, address, playerName, password, 0, 0, NULL, 0);
  170.         if (err != noErr)  HandleError();
  171.         
  172.         NSpReleaseAddressReference(address);
  173.     }
  174.     gHost = false;
  175. }
  176.  
  177.  
  178. // Handles events and sends messages while the mouse is down
  179. void DoHandleEvents(void)
  180. {
  181.     EventRecord                ev;
  182.     Point                    where;
  183.     
  184.     if (Button())
  185.     {
  186.         SetPort(gMyWindow);
  187.         GetMouse(&where);
  188.         UpdateLocation(where);
  189.     }
  190.     
  191.     if (WaitNextEvent(everyEvent, &ev, 0, NULL))
  192.     {
  193.         switch (ev.what)
  194.         {
  195.             case keyDown:
  196.                 gRunning = false;
  197.             break;
  198.         }
  199.     }
  200. }
  201.  
  202.  
  203. // Receives and parses messages
  204. void DoHandleMessages(void)
  205. {
  206.     NSpMessageHeader*        message;
  207.     
  208.     while ((message = NSpMessage_Get(gMyGame)) != NULL)
  209.     {
  210.         switch(message->what)
  211.         {
  212.             case kNSpJoinApproved:
  213.                 DoJoinApproved((NSpJoinApprovedMessage *) message);
  214.             break;
  215.             case kNSpPlayerJoined:
  216.                 DoPlayerJoined((NSpPlayerJoinedMessage*) message);
  217.             break;
  218.             
  219.             case kNSpPlayerLeft:
  220.                 DoPlayerLeft((NSpPlayerLeftMessage*) message);
  221.             break;
  222.             
  223.             case kPlayerLocation:
  224.                 DoPlayerLocation((PlayerLocationMessage*) message);
  225.             break;
  226.         }
  227.         
  228.         NSpMessage_Release(gMyGame, message);
  229.     }
  230. }
  231.  
  232.  
  233. // Remember a new player.
  234. void DoPlayerJoined(NSpPlayerJoinedMessage* message)
  235. {
  236.     PlayerLocation*        player;
  237.     
  238.     if (!gHost && message->playerInfo.id == NSpPlayer_GetMyID(gMyGame))
  239.         return;
  240.         
  241.     // Allocate the memory
  242.     player = (PlayerLocation*) NewPtr(sizeof(PlayerLocation));
  243.     if (player == NULL)  HandleError();
  244.     
  245.     // Link it into the list
  246.     player->next = gPlayerList;
  247.     player->prev = NULL;
  248.     gPlayerList = player;
  249.     
  250.     // Fill it in
  251.     player->id = message->playerInfo.id;
  252.     BlockMove(message->playerInfo.name, player->name, message->playerInfo.name[0]+1);
  253.     player->where.v = 100;
  254.     player->where.h = 200;
  255.     
  256.     // Cause re-render
  257.     gChanged = true;
  258. }
  259.  
  260.  
  261.  
  262. void DoJoinApproved(NSpJoinApprovedMessage* message)
  263. {        
  264.     OSStatus err;
  265.     NSpPlayerEnumerationPtr     thePlayers;
  266.     NSpPlayerInfoPtr    playerInfo;
  267.     PlayerLocation*        player;
  268.     int i;
  269.  
  270.     err = NSpPlayer_GetEnumeration(gMyGame, &thePlayers);
  271.     if (err == noErr)
  272.     {
  273.         for (i = 0; i < thePlayers->count; i++)
  274.         {
  275.             playerInfo = thePlayers->playerInfo[i];
  276.             // Allocate the memory
  277.             player = (PlayerLocation*) NewPtr(sizeof(PlayerLocation));
  278.             if (player == NULL)  HandleError();
  279.             
  280.             // Link it into the list
  281.             player->next = gPlayerList;
  282.             player->prev = NULL;
  283.             gPlayerList = player;
  284.             
  285.             // Fill it in
  286.             player->id = playerInfo->id;
  287.             BlockMove(playerInfo->name, player->name, playerInfo->name[0]+1);
  288.             player->where.v = 100;
  289.             player->where.h = 200;
  290.             
  291.             // Cause re-render
  292.             gChanged = true;
  293.         }
  294.         
  295.         NSpPlayer_ReleaseEnumeration(gMyGame, thePlayers);
  296.     }
  297. }
  298. // Get rid of a player.
  299. void DoPlayerLeft(NSpPlayerLeftMessage* message)
  300. {
  301.     PlayerLocation*        player;
  302.     PlayerLocation*        next;
  303.     PlayerLocation*        prev;
  304.     
  305.     // Find the player from the message sender ID
  306.     player = FindPlayer(message->header.from);
  307.     if (player == NULL)  HandleError();
  308.     
  309.     // Unlink it from the list
  310.     prev = player->prev;
  311.     next = player->next;
  312.     
  313.     if (next != NULL)
  314.     {
  315.         next->prev = prev;
  316.     }
  317.     
  318.     if (prev != NULL)
  319.     {
  320.         prev->next = next;
  321.     }
  322.     else
  323.     {
  324.         gPlayerList = next;
  325.     }
  326.     
  327.     // Get rid of the memory
  328.     DisposePtr((Ptr) player);
  329.     
  330.     // Cause re-render
  331.     gChanged = true;
  332. }
  333.  
  334.  
  335. // Handles a player location message
  336. void DoPlayerLocation(PlayerLocationMessage* message)
  337. {
  338.  
  339.     PlayerLocation*        player;
  340.     
  341.     // Find the player from the message sender ID
  342.     player = FindPlayer(message->header.from);
  343.     if (player == NULL)  HandleError();
  344.     
  345.     // Grab the new location
  346.     player->where = message->where;
  347.     
  348.     // Cause re-render
  349.     gChanged = true;
  350. }
  351.  
  352.  
  353. // Sends a message indicating the new location
  354. void UpdateLocation(Point where)
  355. {
  356.     PlayerLocationMessage    message;
  357.     
  358.     NSpClearMessageHeader(&message.header);
  359.     
  360.     message.header.what = kPlayerLocation;
  361.     message.header.to = kNSpAllPlayers;
  362.     
  363.     message.header.messageLen = sizeof(PlayerLocationMessage);
  364.     message.where = where;
  365.     
  366.     {  //••• TEMPORARY
  367.         #if 0
  368.             long foo;
  369.             Delay(60, &foo);
  370.         #endif
  371.         
  372.         message.header.from = NSpPlayer_GetMyID(gMyGame);
  373.     }
  374.     
  375.     NSpMessage_Send(gMyGame, &message.header, kNSpSendFlag_Normal | kNSpSendFlag_SelfSend);
  376. }
  377.  
  378.  
  379. // Redraws the contents of the window
  380. void Redraw(void)
  381. {
  382.     PlayerLocation*        player;
  383.     
  384.     if (gChanged)
  385.     {
  386.         SetPort(gMyWindow);
  387.         EraseRect(&gMyWindow->portRect);
  388.         
  389.         for (player = gPlayerList; player != NULL; player = player->next)
  390.         {
  391.             MoveTo(player->where.h, player->where.v);
  392.             DrawString(player->name);
  393.         }
  394.         
  395.         gChanged = false;
  396.     }
  397. }
  398.  
  399.  
  400. // Returns a pointer to the structure describing the player given the ID.
  401. // If not found, then NULL is returned.
  402. PlayerLocation* FindPlayer(NSpPlayerID id)
  403. {
  404.     PlayerLocation*        player;
  405.     
  406.     for (player = gPlayerList; player != NULL; player = player->next)
  407.     {
  408.         if (player->id == id)
  409.         {
  410.             return player;
  411.         }
  412.     }
  413.     
  414.     return NULL;
  415. }
  416.  
  417.  
  418.